package com.example.demo;

import java.util.Map;

import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.server.ServerWebExchange;

import com.netflix.loadbalancer.AbstractServerPredicate;
import com.netflix.loadbalancer.PredicateKey;

public class GrayLevelPredicate extends AbstractServerPredicate {

	protected final String grayLevelMark  ;

	public GrayLevelPredicate(String grayLevelMark) {
		super();
		this.grayLevelMark = grayLevelMark;
	}

	@Override
	public boolean apply(@Nullable PredicateKey input) {
		return input != null && input.getServer() instanceof NacosServer && apply((NacosServer) input.getServer());
	}
 
	private String getRequestGrayLevelMark(String mark) {
		final WebRequest request = (WebRequest) RequestContextHolder.getRequestAttributes();
		if(request!=null) { 
			return request.getHeader(mark);
		}
		ServerWebExchange exchange= ServerWebExchangeContextHolder.getServerWebExchange();
		if(exchange!=null) {
			if(exchange.getAttribute(mark)!=null) {
				return exchange.getAttribute(mark);
			}
			return exchange.getRequest().getHeaders().getFirst(mark);
		}
		return null;
	}
	
	protected boolean apply(NacosServer nacosServer) {
 		final Map<String, String> metadata = nacosServer.getInstance().getMetadata();
 		String versionNo = getRequestGrayLevelMark(grayLevelMark);
		String metadataVersion = metadata.get(grayLevelMark);
		return (StringUtils.isEmpty(versionNo) && StringUtils.isEmpty(metadataVersion))
				|| (!StringUtils.isEmpty(versionNo) && versionNo.equals(metadataVersion));
	}
}
